package com.apttbc.looneytuner;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Rect;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

public class LooneyTunerActivity extends Activity {
		
	private Audible audioIn;
	private double primaryFrequency = 0.0;
	private double fourierMagnitude = 0.0;
	private TextView freqDisplay, diffDisplay, noteDisplay, sharpFlatDisplay, magDisplay;
	private int notePlayed;
	private Button toggleBtn;
	private ProgressBar freqGuage;
	private AnimationDrawable frameAnimation;
	private boolean isRecording;
	
	/**
	 * The Handler allows a runnable object to be posted to the thread to which it is assigned. 
	 * In this case, when a valid frequency is computed, mHandler should post callback to the message queue, 
	 * which will in turn cause callback to execute it's 'run' method, which displays the current frequency 
	 * information on the display
	 */
	final Handler mHandler = new Handler();
	final Runnable callback = new Runnable() {
		public void run(){
			primaryFrequency = audioIn.getCurrentFrequency();
			fourierMagnitude = audioIn.getCurrentMagnitude();
			notePlayed = Notes.getNote(primaryFrequency);
			
			if(fourierMagnitude > 100)
				updateGUI();
			else
				magDisplay.setText("" + fourierMagnitude);
		}

	};
	
	
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
    	super.onCreate(savedInstanceState);
    	
        setContentView(R.layout.main);
        toggleBtn = (Button) findViewById(R.id.toggle_btn);
        toggleBtn.setOnClickListener(buttonClick);
        toggleButton(false);
        initLayout(); 
        
        // Load the ImageView that will host the animation and
        // set its background to our AnimationDrawable XML resource.
        ImageView img = (ImageView)findViewById(R.id.imageView1);
        img.setBackgroundResource(R.drawable.android_animator);

        // Get the background, which has been compiled to an AnimationDrawable object.
        frameAnimation = (AnimationDrawable) img.getBackground();
        
        isRecording = false;
        
        lockScreenRotation();
    }
    
    public void onPause(){
    	if(isRecording){
            toggleState();
        }
        super.onPause();
    }
    
    private void initLayout(){
    	freqDisplay = (TextView) findViewById(R.id.freq_textView);
        diffDisplay = (TextView) findViewById(R.id.diff_textView);
        magDisplay = (TextView) findViewById(R.id.mag_textView);
        noteDisplay = (TextView) findViewById(R.id.selected_note);
        sharpFlatDisplay = (TextView) findViewById(R.id.sharpflat_display);
        freqGuage = (ProgressBar) findViewById(R.id.freq_guage);
        freqGuage.setMax(100);
        resetGUI();
    }
    
    private OnClickListener buttonClick = new OnClickListener() {
		
    	
    	boolean start = true;
		@Override
		public void onClick(View v) {
			toggleState();
	        start = !start;			
		}
	};
	
	private void toggleState() {
		if(!isRecording){
//			lockScreenRotation();
            try {
            	// Start the animation (looped playback by default).
                frameAnimation.start();
                audioIn = new Audible(mHandler,callback);
                audioIn.start();
                toggleButton(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        else{
//        	unlockScreenRotation();
        	frameAnimation.stop();
        	audioIn.close();
            toggleButton(false);
        }
		isRecording = !isRecording;
	}
	
    private void toggleButton(boolean isRecording) {
        if(isRecording)
        	toggleBtn.setText(R.string.stop_btn_str);
        else
        	toggleBtn.setText(R.string.start_btn_str);
    }

    private void resetGUI(){
		noteDisplay.setText("");
		freqDisplay.setText("");
		diffDisplay.setText("");
		updateFreqGuage(0);
		sharpFlatDisplay.setText("Play a Note");
	}
	
	private void updateGUI(){
		noteDisplay.setText(Notes.getNoteString(notePlayed));
		freqDisplay.setText("" + primaryFrequency);
		diffDisplay.setText("" + Notes.getDifference(notePlayed, primaryFrequency));
		magDisplay.setText("" + fourierMagnitude);
		double cents = Notes.getCents(notePlayed, primaryFrequency);
		updateFreqGuage(cents);
		updateCentsDisplay(cents);
	}
	
	private void updateFreqGuage(double centsDbl) {
		int cents = (int) Math.round(centsDbl);
//		int centsMargin = 5;
//		
//		Rect bounds = freqGuage.getProgressDrawable().getBounds();
//		if(Math.abs(cents) <= centsMargin)
//			freqGuage.setProgressDrawable(getResources().getDrawable(R.drawable.green_progress));
//		else
//			freqGuage.setProgressDrawable(getResources().getDrawable(R.drawable.red_progress));
//		freqGuage.getProgressDrawable().setBounds(bounds);
		
		if(cents > 50)
			freqGuage.setProgress(100);
		else if (cents < -50)
			freqGuage.setProgress(0);
		else
			freqGuage.setProgress(50 + cents);
						
	}
	
	private void updateCentsDisplay(double cents){
		double precision = 100.0; //keep 2 digits
		cents = Math.round(cents * precision) / precision;
		if(cents > 0)
			sharpFlatDisplay.setText("" + Math.abs(cents) + " Cents Sharp");
		else if (cents < 0)
			sharpFlatDisplay.setText("" + Math.abs(cents) + " Cents Flat");
		else
			sharpFlatDisplay.setText("Tuned");
	}
	
	
	/**
	 * Disable screen rotation and lock the orientation to the current one
	 */
	private void lockScreenRotation() {
		switch (this.getResources().getConfiguration().orientation) {
		case Configuration.ORIENTATION_PORTRAIT:
			this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
			break;
		case Configuration.ORIENTATION_LANDSCAPE:
			this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
			break;
		}
	}
	
	/**
	 * Re-enable screen rotation
	 */
	private void unlockScreenRotation(){
		this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
	}
}